package yourobot;

import java.awt.Color;
import java.util.Random;

import org.jbox2d.collision.shapes.PolygonShape;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.BodyDef;
import org.jbox2d.dynamics.BodyType;
import org.jbox2d.dynamics.FixtureDef;
import org.jbox2d.dynamics.World;
import org.jbox2d.dynamics.contacts.ContactEdge;

import yourobot.config.WallColorConfig;

/**
 * 
 * @author mehdimasrour
 * 
 */
public class Wall {
	private final Body b;
	private final boolean isH;
	private WallType type;
	private final WallColorConfig color;

	static final int WALL_SIZE = 25;
	
	public static enum WallType{
		WOOD, STONE, ICE
	};
	
	
	public Wall(World w, Level l){
		BodyDef bd = new BodyDef();
		bd.type = BodyType.STATIC;
		Random r = new Random(System.nanoTime());
		/*
		 * We don't want walls too close from the 
		 * starting or the finish area
		 */
		
		float x;
		float y;
		do{
			x = r.nextFloat()*Main.MAX_X-50;
			y = r.nextFloat()*Main.MAX_Y-50;
		} while (isTooClose(x, y, l));
		bd.position.set(x, y);
		PolygonShape p = new PolygonShape();
		Boolean bb = r.nextBoolean();
		switch (r.nextInt(3)){
			case 0:
				type=WallType.WOOD;
				break;
			
			case 1:
				type=WallType.STONE;
				break;
			
			case 2:type=WallType.ICE;
			break;
		}
		color = new WallColorConfig(type);
		if ( bb) {
			p.setAsBox(WALL_SIZE,1);
			isH = true;
		}
		else {
			p.setAsBox(1,WALL_SIZE);
			isH = false;
		}
		b = w.createBody(bd);
		FixtureDef fd = new FixtureDef();
		fd.userData = "wall1";
		fd.shape = p;
		fd.restitution = 0.1f;
		b.createFixture(fd);
		b.setLinearDamping(0.2f);
		b.setUserData(this);
	}
	
	/**
	 * 
	 * @return true if the wall is horizontal
	 */
	public boolean isH(){
		return isH;
	}
	
	/**
	 * 
	 * @return the type of wall (WOOD, STONE, ICE)
	 */
	public WallType getType(){
		return type;
	}
	
	/**
	 * 
	 * @return the wall's body
	 */
	public Body getBody(){
		return b;
	}
	
	/**
	 * 
	 * @return the color of the all (depends on the type)
	 */
	public Color getColor(){
		return color.getColor();
	}
	
	/**
	 * 
	 * @param x x position where the wall should be placed
	 * @param y y position where the wall should be placed
	 * @param l Level in which the wall whould be placed
	 * @return true if the wall is too close from the starting or finish area
	 */
	public boolean isTooClose(float x, float y, Level l){
		float x_start;
		float x_end;
		float y_start;
		float y_end;
		x_start = l.getStart().x;
		x_end = l.getEnd().x;
		y_start = l.getStart().y;
		y_end = l.getEnd().y;
		return (Math.abs(x_start-x)<55 || Math.abs(x_end-x)<55) && (Math.abs(y_start-y)<55 || Math.abs(y_end-y)<55);
	}
	
	/**
	 * Checks if the Wall is still moving fast enough to keep it dynamic
	 * or (in case of snap) if the wall is not being touched by a player
	 */
	public void check(){
		float f = b.getLinearVelocity().length();
		if (f < 25 ){
			ContactEdge c = b.getContactList();
			if ( c == null ){
				b.setType(BodyType.STATIC);
			}
		}
	}
	
	/**
	 * 
	 * @return the wall's position
	 */
	public Vec2 getPosition(){
		return b.getPosition();
	}
}
